import { Ref, nextTick } from 'vue'
import { useTableDrag, Item, swapIndex } from '@/components'
import { setLocal, getLocal, reomveLocal } from './local'

/**
 * 自定义Table设置 
 * @param Table_ref Table Dom引用 用于获取Dom元素进行动画
 * @param sourceList_ref  原始数据（包含children树形结构）
 * @returns 
 */
export const useTableCustom = (Table_ref: Ref, sourceList_ref: Ref<Item[]>) => {

  // Table Dom引用
  const TableRef: Ref = Table_ref
  // 原始数据
  const sourceListRef: Ref<Item[]> = sourceList_ref
  const tableDragHandler = useTableDrag(sourceListRef)
  tableDragHandler.init()

  /**
   * 是否禁用 [ 上移 | 下移 | 置顶 | 置底 ] 操作
   * @param item 
   * @returns 
   */
  const isDisabledMove = (item: Item) => {
    const { fixed } = item
    
    // 获取nodeId节点所在的数组
    const list: Item[] = tableDragHandler.getSameNodeList(item)
    // 获取下标
    let index = tableDragHandler.getNodeIndex(list, item)

    const leftNum = list.filter((item) => item.fixed === 'left' || item.fixed === true).length
    const middleNum = list.filter((item) => !item.fixed).length
    const rightNum = list.filter((item) => item.fixed === 'right').length

    // 禁用的操作集合
    const disabledMap = {
      up: false,      // 上移
      down: false,    // 下移
      top: false,     // 置顶
      bottom: false,  // 置底
    }

    if (index === 0) {
      disabledMap.top = true
      disabledMap.up = true
    } else if (index === list.length - 1) {
      disabledMap.bottom = true
      disabledMap.down = true
    }

    // 固定在右边的 不能置顶和移动到中间区域
    if (fixed === 'right') {
      disabledMap.top = true
      if (leftNum + middleNum === index) {
        disabledMap.up = true
      }
    }
    // 固定在左边的 不能置底和移动到中间区域
    else if (fixed === 'left' || fixed === true) {
      disabledMap.bottom = true
      if (leftNum === index + 1) {
        disabledMap.down = true
      }
    }
    // 中间的元素 
    else {
      if (leftNum === index) {
        disabledMap.up = true
        disabledMap.top = true
      }
      if (leftNum + middleNum === index + 1) {
        disabledMap.down = true
        disabledMap.bottom = true
      }
    }

    return disabledMap
  }


  /**
   * 根据fixed顺序排列
   * @param list 
   */
  const sortByFixed = () => {
    const list = sourceListRef.value
    list.sort((prev, next) => {
      let prevFlag = 0
      if (prev.fixed === 'right') {
        prevFlag = 1
      } else if (prev.fixed) {
        prevFlag = -1
      }
      let nextFlag = 0
      if (next.fixed === 'right') {
        nextFlag = 1
      } else if (next.fixed) {
        nextFlag = -1
      }
      return prevFlag - nextFlag
    })
  }


  /**
   * 表格行Dom移动动画
   * @param item1 
   * @param item2 
   * @param type 
   * @returns 
   */
  const moveRowElement = (itemList_1: any[], itemList_2: any[], type: 'up' | 'down' | 'top' | 'bottom') => {

    const itemTop_1 = itemList_1[0].offsetTop
    const itemTop_2 = itemList_2[0].offsetTop
    // 判断上移 | 下移 的list
    const upList   = itemTop_1 > itemTop_2 ? itemList_1 : itemList_2
    const downList = itemTop_1 < itemTop_2 ? itemList_1 : itemList_2
    const allList = [...itemList_1, ...itemList_2]
    allList.forEach(item=>{
      item.style.transition = 'transform 0.5s ease-in-out'
      item.style.zIndex = '10'
    })
    if (type === 'up' || type === 'top') {
      downList.forEach(item=>{
        item.style.transitionDelay = '0.2s'
        item.style.zIndex = '5'
      })
    } else {
      upList.forEach(item=>{
        item.style.transitionDelay = '0.2s'
        item.style.zIndex = '5'
      })
    }

    const upTop = upList[0].offsetTop
    const downTop = downList[0].offsetTop
    const upHeight = upList.reduce((total, item) => total + item.offsetHeight, 0)
    const downHeight = downList.reduce((total, item) => total + item.offsetHeight, 0)
    if (type === 'top') {
      upList.forEach(item=>{
        item.style.transform = `translateY(${-(Math.abs(upTop - downTop))}px)`
      })
      return 
    }
    if (type === 'bottom') {
      downList.forEach(item=>{
        item.style.transform = `translateY(${(Math.abs((upTop + upHeight) - (downTop + downHeight)))}px)`
      })
      return 
    }

    // 需要2组元素都移动的
    upList.forEach(item=>{
      item.style.transform = `translateY(${-downHeight}px)`
    })
    downList.forEach(item=>{
      item.style.transform = `translateY(${upHeight}px)`
    })
  }

  
  // 清除样式
  const clearStyle = (tableRowElList) => {
    for (let index = 0; index < tableRowElList.length; index++) {
      const element = tableRowElList[index]
      element.removeAttribute('style')
      element.classList.add('move')
    }
  }


  /**
   * 上移
   * @param item 
   * @param rowIndex 页面视图Dom元素数组下标（扁平化后的数组）
   * @param 步长移动几行 默认1 
   */
  const moveUp = (item: Item, rowIndex: number, step=1) => {
    const list: Item[] = tableDragHandler.getSameNodeList(item)
    const index = tableDragHandler.getNodeIndex(list, item)
    // 当前节点和所包含子级加起来数量
    const currentItemCount = 1 + tableDragHandler.getChildrenCount(item)
    // 目标节点和所包含子级加起来数量
    let targetItemCount = 0
    for(let curStep = 1; curStep <= step; curStep++) {
      const targetItem: Item = list[index - curStep]
      targetItemCount = 1 + tableDragHandler.getChildrenCount(targetItem)
    }
    // 获取DOM 用于动画
    const tableRowElList: any[] = TableRef.value.$el.querySelectorAll('.el-table__row')
    const currentElList = [...tableRowElList].slice(rowIndex, rowIndex + currentItemCount)
    const targetElList = [...tableRowElList].slice(rowIndex - targetItemCount, rowIndex)
    moveRowElement(currentElList, targetElList, 'up')

    setTimeout(() => {
      if (index - step >= 0) {
        swapIndex(list, index, index - step)
      }
      clearStyle(tableRowElList)
    }, 500)
  }


  /**
   * 下移
   * @param item 
   * @param rowIndex 页面视图Dom元素数组下标（扁平化后的数组）
   * @param 步长移动几行 默认1 
   */
  const moveDown = (item: Item, rowIndex: number, step=1) => {
    const list: Item[] = tableDragHandler.getSameNodeList(item)
    const index = tableDragHandler.getNodeIndex(list, item)
    // 当前节点和所包含子级加起来数量
    const currentItemCount = 1 + tableDragHandler.getChildrenCount(item)
    // 目标节点和所包含子级加起来数量
    let targetItemCount = 0
    for(let curStep = 1; curStep <= step; curStep++) {
      const targetItem: Item = list[index + curStep]
      targetItemCount += 1 + tableDragHandler.getChildrenCount(targetItem)
    }
    // 获取DOM 用于动画
    const tableRowElList = TableRef.value.$el.querySelectorAll('.el-table__row')
    const currentElList = [...tableRowElList].slice(rowIndex, rowIndex + currentItemCount)
    const targetElList = [...tableRowElList].slice(rowIndex + currentItemCount, rowIndex + currentItemCount + targetItemCount)
    moveRowElement(currentElList, targetElList, 'down')

    setTimeout(() => {
      if (index + step <= list.length - 1) {
        swapIndex(list, index, index + step)
      }
      clearStyle(tableRowElList)
    }, 500)
  }


  /**
   * 移动到顶部
   * @param item 
   * @param rowIndex 页面视图Dom元素数组下标（扁平化后的数组）
   */
  const moveTop = (item: Item, rowIndex) => {
    const list: Item[] = tableDragHandler.getSameNodeList(item)
    const leftNum = list.filter((item) => item.fixed === 'left' || item.fixed === true).length
    const currentIsFixed = item.fixed === 'left' || item.fixed === true
    const index = tableDragHandler.getNodeIndex(list, item)
    // 当前节点和所包含子级加起来数量
    const currentItemCount = 1 + tableDragHandler.getChildrenCount(item)
    const targetItem: Item = list[0]
    const flatList = tableDragHandler.getFlatList()
    const topIndex = tableDragHandler.getNodeIndex(flatList, targetItem)
    console.log('topIndex', topIndex)
    // 获取DOM 用于动画
    const tableRowElList = TableRef.value.$el.querySelectorAll('.el-table__row')
    const currentElList = [...tableRowElList].slice(rowIndex, rowIndex + currentItemCount)
    console.log('currentIsFixed ? 0 : Math.max(leftNum, topIndex)', currentIsFixed ? 0 : Math.max(leftNum, topIndex))
    const targetEl = tableRowElList[currentIsFixed ? 0 : Math.max(leftNum, topIndex)]
    moveRowElement(currentElList, [targetEl], 'top')

    setTimeout(() => {
      const [temp] = list.splice(index, 1)
      nextTick(() => {
        list.splice(currentIsFixed ? 0 : leftNum, 0, temp)
        clearStyle(tableRowElList)
      })
    }, 500)
  }


  /**
   * 移动到底部
   * @param item 
   * @param rowIndex 页面视图Dom元素数组下标（扁平化后的数组）
   */
  const moveBottom = (item: Item, rowIndex) => {
    const list: Item[] = tableDragHandler.getSameNodeList(item)
    const index = tableDragHandler.getNodeIndex(list, item)
    const rightNum = list.filter((item) => item.fixed === 'right').length
    const currentIsFixed = item.fixed === 'right'
    // 当前节点和所包含子级加起来数量
    const currentItemCount = 1 + tableDragHandler.getChildrenCount(item)
    const targetItem: Item = list[list.length-1]
    const flatList = tableDragHandler.getFlatList()
    const bottomIndex = tableDragHandler.getNodeIndex(flatList, targetItem)
    // 获取DOM 用于动画
    const tableRowElList = TableRef.value.$el.querySelectorAll('.el-table__row')
    const currentElList = [...tableRowElList].slice(rowIndex, rowIndex + currentItemCount)
    const targetEl = tableRowElList[currentIsFixed ? tableRowElList.length - 1 : Math.min(tableRowElList.length - 1 - rightNum, bottomIndex)]
    moveRowElement(currentElList, [targetEl], 'bottom')

    setTimeout(() => {
      const [temp] = list.splice(index, 1)
      nextTick(() => {
        list.splice(currentIsFixed ? list.length : list.length -  rightNum, 0, temp)
        clearStyle(tableRowElList)
      })
    }, 500)
  }


  /**
   * 切换固定列
   * @param item  
   * @param rowIndex 页面视图Dom元素数组下标（扁平化后的数组）
   * @param fixed 固定左侧|右侧
   * @param flag  确认固定|取消固定
   */
  const swicthFixed = (item: Item, rowIndex: number, fixed: 'left' | 'right', flag: boolean) => {
    const oldFixed = item.fixed
    if(flag) {
      fixed === 'left' ? moveTop(item, rowIndex) : moveBottom(item, rowIndex)
      item.fixed = fixed
    } else  {
      item.fixed = false
      // 获取nodeId节点所在的数组
      const list: Item[] = tableDragHandler.getSameNodeList(item)
      const index = tableDragHandler.getNodeIndex(list, item)
      const leftNum = list.filter((item) => item.fixed === 'left' || item.fixed === true).length
      const rightNum = list.filter((item) => item.fixed === 'right').length
      if (oldFixed === 'left') {
        moveDown(item, rowIndex, leftNum - index) 
      } else if (oldFixed === 'right') {
        moveUp(item, rowIndex, rightNum - (list.length -1 - index))
      }
    }
  }


  // 拖动事件
  const dragMove = (event: any) => {
    const { dragged, related } = event

    const currentIsFixed = related.classList.contains('fixed-row')
    if (currentIsFixed) {
      // 有fixed标志, 不是居左就是居右
      const isLeft = related.classList.contains('fixed-left')
      if (isLeft) {
        // 只能在左侧区域移动
        if (!dragged.classList.contains('fixed-left')) {
          return false
        }
      } else {
        // 只能在右侧区域移动
        if (!dragged.classList.contains('fixed-right')) {
          return false
        }
      }
    } else {
      // 只能在非fixed的区域移动
      if (dragged.classList.contains('fixed-row')) {
        return false
      }
    }
  }

  return {
    isDisabledMove,
    sortByFixed,
    moveUp,
    moveDown,
    moveTop,
    moveBottom,
    swicthFixed,
    dragMove,
    isChildren: tableDragHandler.isChildren
  }
}
// 设置初始Filter本地数据
export const setInitFilterData = (id: string, customFilters: Item[], columnNum: number) => {
  let oldConfigList = getLocal('filterConfig') || []
  const foundObject = oldConfigList.find((obj) => String(obj.filterId) === String(id))
  if (!foundObject) {
    customFilters.forEach((item, index) => {
      //设置查询数据的显隐
      if (index > columnNum * 1 - 2) {
        item.visible = false
      } else {
        item.visible = true
      }
    })
    const configMap = {
      filterId: id,
      info: {
        expandType: 1,
        filterArray: []
      }
    }
    // 去除同名
    oldConfigList = [...oldConfigList.filter((oldItem) => oldItem.filterId !== id)]
    setLocal('filterConfig', [...oldConfigList, configMap])
  }
}


